package com.ja.openchat.viewmodels;

import android.app.AlertDialog;
import android.app.Application;
import android.content.DialogInterface;
import android.view.View;

import androidx.annotation.NonNull;
import androidx.databinding.ObservableField;
import androidx.fragment.app.FragmentActivity;
import androidx.recyclerview.widget.DiffUtil;
import androidx.recyclerview.widget.LinearLayoutManager;
import androidx.recyclerview.widget.RecyclerView;

import com.chad.library.adapter.base.BaseQuickAdapter;
import com.chad.library.adapter.base.listener.OnItemChildClickListener;
import com.chad.library.adapter.base.listener.OnItemClickListener;
import com.google.gson.JsonObject;
import com.ja.openchat.R;
import com.ja.openchat.ui.chat.ChatActivity;
import com.ja.openchat.ui.contact.MobileContactFragment;
import com.ja.openchat.ui.me.QrCodeFragment;
import com.ja.openchat.ui.message.ScanActivity;
import com.ja.openchat.ui.message.SearchAvatarDiffCallBack;
import com.ja.openchat.ui.message.adapter.SearchContactAdapter;
import com.ja.openchat.views.ChatUserDialog;
import com.ja.openchat.views.ExLinearLayoutManager;
import com.lxj.xpopup.XPopup;
import com.zy.openchat.core.manager.TelegramManager;
import com.zy.openchat.core.manager.TgEvent;
import com.zy.openchat.core.manager.TgResponse;
import com.zy.openchat.core.manager.TgResultBlock;
import com.zy.openchat.core.model.message.ChatInfo;
import com.zy.openchat.core.model.message.KeyValueTriple;
import com.zy.openchat.core.model.user.OrgUserInfo;
import com.zy.openchat.core.model.user.UserInfo;
import com.zy.openchat.util.Common;

import org.apache.commons.lang3.StringUtils;
import org.greenrobot.eventbus.Subscribe;
import org.greenrobot.eventbus.ThreadMode;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import io.reactivex.Observable;
import io.reactivex.ObservableEmitter;
import io.reactivex.ObservableOnSubscribe;
import io.reactivex.android.schedulers.AndroidSchedulers;
import io.reactivex.functions.Consumer;
import io.reactivex.schedulers.Schedulers;
import me.goldze.mvvmhabit.base.BaseModel;
import me.goldze.mvvmhabit.base.BaseViewModel;
import me.goldze.mvvmhabit.binding.command.BindingAction;
import me.goldze.mvvmhabit.binding.command.BindingCommand;

public class AddContactFragmentViewModel extends BaseViewModel {

    private final Application mApplication;
    private FragmentActivity activity;
    private View view;

    public ObservableField<String> userNameSub = new ObservableField<>(StringUtils.isEmpty(UserInfo.getUserInfo().username) ? "" : ("@" + UserInfo.getUserInfo().username));

    public AddContactFragmentViewModel(@NonNull Application application, BaseModel mRepository) {
        super(application);
        mApplication = application;
    }
    public ObservableField<String> my_user_value = new ObservableField<>("我的用户名：");

    public ObservableField<Boolean> noData = new ObservableField<Boolean>(true);


    public BindingCommand scan_btn = new BindingCommand(new BindingAction() {
        @Override
        public void call() {
            startActivityForResult(ScanActivity.class,100);
        }
    });

    public BindingCommand my_user_value_click = new BindingCommand(new BindingAction() {
        @Override
        public void call() {
            startContainerActivity(QrCodeFragment.class.getCanonicalName());
        }
    });

    public BindingCommand add_phone_contact = new BindingCommand(new BindingAction() {
        @Override
        public void call() {
            startContainerActivity(MobileContactFragment.class.getCanonicalName());
        }
    });


    private List<ChatInfo> totalContactsList = new ArrayList<>();
    private SearchContactAdapter publicSearchSectionAdapter;

    public void doSearch(final String keyword,int positon) {
        totalContactsList.clear();
        if(positon==0){
            TelegramManager.getTelegramManager().searchChatsList(getApplication(), keyword, new TgResultBlock<List<Long>>() {
                @Override
                public void onResult(Map<String, Object> request, JsonObject response, List<Long> chatIds) {
                    firstSearchResult(keyword,chatIds,positon);
                }

                @Override
                public void onTimeout(Map<String, Object> request) {
                    firstSearchResult(keyword,null,positon);
                }
            });
        }else{
            TelegramManager.getTelegramManager().searchMyChatsList(getApplication(), keyword, new TgResultBlock<List<Long>>() {
                @Override
                public void onResult(Map<String, Object> request, JsonObject response, List<Long> chatIds) {
                    firstSearchResult(keyword,chatIds, positon);
                }

                @Override
                public void onTimeout(Map<String, Object> request) {
                    firstSearchResult(keyword,null, positon);
                }
            });
        }


    }

    private void firstSearchResult(String keyword,List<Long> privateChats,int positon){
        TelegramManager.getTelegramManager().searchPublicChatsList(getApplication(), keyword, new TgResultBlock<List<Long>>() {
            @Override
            public void onResult(Map<String, Object> request, JsonObject response, List<Long> chatIds) {
                initSearchResult(chatIds,privateChats, positon);
            }

            @Override
            public void onTimeout(Map<String, Object> request) {
                initSearchResult(null,privateChats, positon);
            }
        });
    }


    private void initSearchResult(List<Long> publicChatIds,List<Long> privateChatIds,int positon){
        if (!Common.isEmpty(publicChatIds)||!Common.isEmpty(privateChatIds)) {
            HashMap<Long, KeyValueTriple<Boolean,Boolean,ChatInfo>> hashMap = new HashMap<>();
            if(!Common.isEmpty(publicChatIds)){
                for(long chatId:publicChatIds){
                    hashMap.put(chatId,new KeyValueTriple<>(true,true,null));
                }
            }
            if(!Common.isEmpty(privateChatIds)){
                for(long chatId:privateChatIds){
                    KeyValueTriple<Boolean,Boolean,ChatInfo> chatInfoPair = hashMap.get(chatId);
                    if(chatInfoPair!=null){
                        chatInfoPair.first = false;
                        hashMap.put(chatId,chatInfoPair);
                    }else{
                        hashMap.put(chatId,new KeyValueTriple<Boolean,Boolean,ChatInfo>(false,true,null));
                    }

                }
            }
            if(hashMap.size()>0){
                for(long chatId:hashMap.keySet()){

                    TelegramManager.getTelegramManager().requestChatInfoByChatId(getApplication(), chatId, new TgResultBlock<ChatInfo>() {
                        @Override
                        public void onResult(Map<String, Object> request, JsonObject response, ChatInfo obj) {
                            KeyValueTriple<Boolean,Boolean,ChatInfo> chatInfoPair = hashMap.get(chatId);
                            if(chatInfoPair!=null){
                                chatInfoPair.third = obj;
                            }
                            hashMap.put(chatId,chatInfoPair);
                            reloadListUI(hashMap,positon);
                        }

                        @Override
                        public void onTimeout(Map<String, Object> request) {

                        }
                    });
                }
            }
        }else{
            reloadListUI(null, positon);
        }
    }

    public void initList(RecyclerView recyclerView) {
        //初始化列表
        LinearLayoutManager layoutManager = new ExLinearLayoutManager(getApplication());
        layoutManager.setOrientation(LinearLayoutManager.VERTICAL);
        recyclerView.setLayoutManager(layoutManager);
        publicSearchSectionAdapter = new SearchContactAdapter(totalContactsList);
        recyclerView.setAdapter(publicSearchSectionAdapter);

        //点击事件
        publicSearchSectionAdapter.setOnItemClickListener(new OnItemClickListener() {
            @Override
            public void onItemClick(@NonNull BaseQuickAdapter<?, ?> adapter, @NonNull View view, int position) {
                ChatInfo chatInfo = publicSearchSectionAdapter.getItemOrNull(position);
                if(chatInfo!=null){
//                    ChatActivity.startActivity(getApplication(),chatInfo);

                    if(chatInfo.isGroup()){
                        ChatActivity.startActivity(getApplication(),chatInfo);
                    }else{
                        UserInfo userInfo = UserInfo.getUserInfo(chatInfo.type.user_id);
                        if(userInfo!=null){
                            boolean blockContact = !(chatInfo.permissions != null && !chatInfo.permissions.banWhisper);
                            new XPopup.Builder(activity)
                                    .hasShadowBg(true)
                                    .isDestroyOnDismiss(true)
                                    .dismissOnTouchOutside(true)
                                    .borderRadius(10)
                                    .atView(view)
                                    .asCustom(new ChatUserDialog(activity, userInfo,blockContact, new ChatUserDialog.OnItemClickListner() {
                                        @Override
                                        public void clickPostion(int postion, ChatInfo chatInfo) {

                                        }
                                    })).show();
                        }
                    }


                }
            }
        });
        publicSearchSectionAdapter.setOnItemChildClickListener(new OnItemChildClickListener() {
            @Override
            public void onItemChildClick(@NonNull BaseQuickAdapter adapter, @NonNull View view, int position) {
                ChatInfo chatInfo = publicSearchSectionAdapter.getItemOrNull(position);
                if(chatInfo!=null){
                    if(chatInfo.isGroup()){
                        ChatActivity.startActivity(getApplication(),chatInfo);
                    }else{
                        UserInfo userInfo = UserInfo.getUserInfo(chatInfo.type.user_id);
                        if(userInfo!=null){
                            clickAdd(userInfo);
                        }
                    }
                }
            }
        });
        getLoginOrgUserInfo();
    }


    private void getLoginOrgUserInfo(){
        TelegramManager.getTelegramManager().requestOrgContactInfo(activity, UserInfo.getUserInfo().id, new TgResultBlock<OrgUserInfo>() {
            @Override
            public void onResult(Map<String, Object> request, JsonObject response, OrgUserInfo obj) {
                publicSearchSectionAdapter.setLoginOrgUserInfo(obj);
            }

            @Override
            public void onTimeout(Map<String, Object> request) {
            }
        });
    }


    private void clickAdd(UserInfo user) {//添加好友
        AlertDialog.Builder dialog = new AlertDialog.Builder(activity);
        dialog.setTitle(R.string.dialog_title_tip).setMessage(String.format(activity.getString(R.string.want_to_add_somebody_friend), user.displayName()));
        dialog.setPositiveButton(R.string.dialog_ok,
                new DialogInterface.OnClickListener() {
                    @Override
                    public void onClick(DialogInterface dialog, int which) {
                        doAddContact(user);
                    }
                });
        dialog.setNegativeButton(R.string.dialog_cancel, new DialogInterface.OnClickListener() {
            @Override
            public void onClick(DialogInterface dialog, int which) {
                dialog.dismiss();
            }
        });
        dialog.show();
    }

    private void doAddContact(UserInfo user) {
        showProgress();
        TelegramManager.getTelegramManager().addContact(getApplication(), user, new TgResultBlock<TgResponse>() {
            @Override
            public void onResult(Map<String, Object> request, JsonObject response, TgResponse obj) {
                hideProgress();
                if (!obj.ok) {
                    showErrorTip("添加好友失败，请稍后重试, " + obj.errString);
                } else {
                    showWarnTip(String.format("[%s]已被添加到您的好友列表中", user.displayName()));
                    TelegramManager.getTelegramManager().sendBeFriendMessage(getApplication(), user.id, new TgResultBlock<TgResponse>() {
                        @Override
                        public void onResult(Map<String, Object> request, JsonObject response, TgResponse obj) {
                        }

                        @Override
                        public void onTimeout(Map<String, Object> request) {
                        }
                    });
                }
            }

            @Override
            public void onTimeout(Map<String, Object> request) {
                hideProgress();
                showErrorTip("添加好友失败，请稍后重试");
            }
        });
    }

    private void reloadListUI(HashMap<Long, KeyValueTriple<Boolean,Boolean,ChatInfo>> hashMap, int positon){
        if(hashMap!=null&&hashMap.size()>0){
            for (Long o : hashMap.keySet()) {
                KeyValueTriple<Boolean,Boolean,ChatInfo> chatInfoPair = hashMap.get(o);
                if(chatInfoPair!=null&&chatInfoPair.third!=null){
                    ChatInfo fullInfo = chatInfoPair.third;
                    if(positon==0){
                        if(fullInfo != null && !fullInfo.isGroup()&&chatInfoPair.second){
                            chatInfoPair.second = false;
                            totalContactsList.add(fullInfo);
                        }
                    }else{
                        if(fullInfo != null && fullInfo.isSuperGroup()&&chatInfoPair.second){
                            chatInfoPair.second = false;
                            fullInfo.isMine = !chatInfoPair.first;
                            totalContactsList.add(fullInfo);
                        }
                    }
                }
            }
        }
        publicSearchSectionAdapter.notifyDataSetChanged();
    }


    @Subscribe(threadMode = ThreadMode.MAIN)
    public void onTgEvent(TgEvent tg_event) {
        if(tg_event == null){
            return;
        }
        switch (tg_event.event){
            case EUser_Td_Contact_Photo_Ok:
            case EUser_Td_UpdateContactInfo:
            case EUser_Td_AddNewContactInfo:
                if((tg_event.data instanceof UserInfo)){
                    UserInfo userInfo = (UserInfo)tg_event.data;
                    Observable.create(new ObservableOnSubscribe<DiffUtil.DiffResult>() {
                                @Override
                                public void subscribe(ObservableEmitter<DiffUtil.DiffResult> e) {
                                    DiffUtil.DiffResult diffResult = DiffUtil.calculateDiff(new SearchAvatarDiffCallBack(totalContactsList, totalContactsList), false);
                                    e.onNext(diffResult);
                                }
                            }).subscribeOn(Schedulers.computation())
                            .observeOn(AndroidSchedulers.mainThread())
                            .subscribe(new Consumer<DiffUtil.DiffResult>() {
                                @Override
                                public void accept(DiffUtil.DiffResult diffResult) {
                                    diffResult.dispatchUpdatesTo(publicSearchSectionAdapter);
                                }
                            });


                    int length = publicSearchSectionAdapter.getData().size();
                    for(int i = 0;i<length;i++){
                        ChatInfo chatInfo = publicSearchSectionAdapter.getItemOrNull(i);
                        if(chatInfo!=null&&chatInfo.userId() == userInfo.id){
                            chatInfo.isMine = userInfo.is_contact;
                            publicSearchSectionAdapter.notifyItemChanged(i);
                            break;
                        }
                    }
                }
                break;
            case EUser_Td_Group_Photo_Ok:
                publicSearchSectionAdapter.notifyDataSetChanged();
                break;
        }
    }

    public void setActivity(FragmentActivity activity) {
        this.activity = activity;
    }

}
